home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / dev / src / wangisrc.lha / wangi / z / GMulti / GMulti.c < prev    next >
C/C++ Source or Header  |  1996-03-27  |  13KB  |  526 lines

  1. /***************************************************************************
  2.  * GMulti.c
  3.  *
  4.  * GMulti, Copyright ©1996 Lee Kindness.
  5.  *
  6.  * Patches:
  7.  *  gotcha.library GL_FindNode()
  8.  *
  9.  * This source is for example purposes...
  10.  *
  11.  */
  12.  
  13. /* This is version... */
  14. #define VERSION "1.1"
  15.  
  16. /* All our includes are in this file */
  17. #include "gst.c"
  18.  
  19. /* download dev/c/SFPatch.lha for documentation */ 
  20. #include "SFPatch.h"
  21.  
  22. /* Libraries used, don't auto open them SAS/C :) */
  23. extern struct IntuitionBase *IntuitionBase = NULL;
  24. extern struct Library *CxBase = NULL;
  25. struct Library *GotchaLibBase = NULL;
  26.  
  27. /* Save a bit of typing */
  28. #define REG(x) register __ ## x
  29.  
  30. /* Library Vector Offsets */
  31. #define FN_OFFSET -54
  32.  
  33. /* GL_FindNode(address,context,info,pat)(A0/A1/A2/A3) */
  34. typedef LONG __asm (*FN_Caller)( REG(a0) struct gl_address *,
  35.                                  REG(a1) struct gl_context *,
  36.                                  REG(a2) struct gl_nodeinfo *,
  37.                                  REG(a3) struct gl_pattern *,
  38.                                  REG(a6) struct Library *);
  39.  
  40. /* We alloc one of these per MULTILINE entry in the cfg file */
  41. struct MLNode 
  42. {
  43.     struct MLNode    *ml_Succ;        /* Next MLNode */
  44.     struct MLNode    *ml_Pred;        /* Previous MLNode */
  45.     UBYTE             ml_reserved1;   /* unused nl_Type */
  46.     BYTE              ml_Flags;       /* Option flags  */
  47.     STRPTR            ml_ReplaceWith; /* text array of subsitutes */
  48.     struct gl_address ml_BaseNode;    /* The node this MLNode deals with */
  49.     STRPTR            ml_Last;        /* Last number/node used */
  50. };
  51.  
  52. /* Flags for ml_Flags */
  53. #define MLFB_COPYPASS 0
  54. #define MLFF_COPYPASS 1
  55.  
  56. /* Constants for ml_Last */
  57. #define MLLAST_NONE (STRPTR)~0
  58. #define MLLAST_BASENODE NULL
  59.  
  60. /* To hold all the MLNodes */
  61. struct MLList 
  62. {
  63.     struct MLNode *mllh_Head;
  64.     struct MLNode *mllh_Tail;
  65.     struct MLNode *mllh_TailPred;
  66. };
  67.  
  68. /* Prototypes */
  69. LONG __asm FN_New( REG(a0) struct gl_address *,
  70.                    REG(a1) struct gl_context *,
  71.                    REG(a2) struct gl_nodeinfo *,
  72.                    REG(a3) struct gl_pattern *,
  73.                    REG(a6) struct Library *);
  74.  
  75. BOOL OpenLibs(void);
  76. void CloseLibs(void);
  77. BOOL ShowWindow(void);
  78. LONG OpenCfg(STRPTR filename);
  79.  
  80. /* Global vars */
  81. SetFunc *FN_SetFunc = NULL;
  82. struct Remember *grk;
  83. BOOL Active;
  84. struct MLList *mlines;
  85. char vertag[] = "$VER: GMulti "VERSION" "__AMIGADATE__;
  86.  
  87. #define DEF_CFGFILE "MAIL:MultiLine.cfg"
  88.  
  89.  
  90. /***************************************************************************
  91.  * main() --
  92.  */
  93. int main(int argc, char **argv)
  94. {
  95.     int ret = RETURN_FAIL;
  96.     Active = TRUE;
  97.     grk = NULL;
  98.     
  99.     /* check version */
  100.     if (OpenLibs()) 
  101.     {
  102.         struct NewBroker nb = 
  103.         {
  104.             NB_VERSION,
  105.             "GMulti",
  106.             &vertag[6],
  107.             "gotcha.library - Better multinode handling",
  108.             NBU_UNIQUE | NBU_NOTIFY,
  109.             COF_SHOW_HIDE,
  110.             -1,
  111.             NULL,
  112.             0
  113.         };
  114.         CxObj *broker;
  115.         nb.nb_Pri = 0;
  116.                 
  117.         if ((nb.nb_Port = CreateMsgPort()) && (broker = CxBroker(&nb, NULL))) 
  118.         {
  119.             STRPTR filename;
  120.         
  121.             if( argc == 2 )
  122.                 filename = argv[1];
  123.             else
  124.                 filename = DEF_CFGFILE;
  125.             
  126.             if( OpenCfg(filename) )
  127.             {
  128.                 /* Alloc our SetFunc's */
  129.                 if( FN_SetFunc = AllocVec(sizeof(SetFunc), MEMF_CLEAR) )
  130.                 {
  131.                     /* init. sfs */
  132.                     FN_SetFunc->sf_Func = FN_New;
  133.                     FN_SetFunc->sf_Library = GotchaLibBase;
  134.                     FN_SetFunc->sf_Offset = FN_OFFSET;
  135.                     FN_SetFunc->sf_QuitMethod = SFQ_COUNT;
  136.  
  137.                     /* Replace the functions */
  138.                     if ( SFReplace(FN_SetFunc) ) 
  139.                     {
  140.                         ULONG sig, sret;
  141.                         BOOL finished;
  142.                     
  143.                         ActivateCxObj(broker, 1L);
  144.  
  145.                         ret = RETURN_OK;
  146.                         
  147.                         finished = FALSE;
  148.                         sig = 1 << nb.nb_Port->mp_SigBit;
  149.                     
  150.                         do 
  151.                         {
  152.                             sret = Wait(SIGBREAKF_CTRL_C | sig);
  153.                             if (sret & sig) 
  154.                             {
  155.                                 CxMsg *msg;
  156.                                 while(msg = (CxMsg *)GetMsg(nb.nb_Port)) 
  157.                                 {
  158.                                     switch(CxMsgType(msg)) 
  159.                                     {
  160.                                         case CXM_COMMAND:
  161.                                             switch(CxMsgID(msg)) 
  162.                                             {
  163.                                                 case CXCMD_DISABLE:
  164.                                                     ActivateCxObj(broker, 0L);
  165.                                                     Active = FALSE;
  166.                                                     break;
  167.                                                 case CXCMD_ENABLE:
  168.                                                     ActivateCxObj(broker, 1L);
  169.                                                     Active = TRUE;
  170.                                                     break;
  171.                                                 case CXCMD_KILL:
  172.                                                     finished = TRUE;
  173.                                                     break;
  174.                                                 case CXCMD_UNIQUE:
  175.                                                     finished = ShowWindow();
  176.                                                     break;
  177.                                                 case CXCMD_APPEAR:
  178.                                                     finished = ShowWindow();
  179.                                                     break;
  180.                                             }
  181.                                             break;
  182.                                     }
  183.                                     ReplyMsg((struct Message *)msg);
  184.                                 }
  185.                             }
  186.                             if (sret & SIGBREAKF_CTRL_C)
  187.                                 finished = TRUE;
  188.                         } while (!finished);
  189.                         ActivateCxObj(broker, 0L);
  190.         
  191.                         /* Restore functions */
  192.                         SFRestore(FN_SetFunc);
  193.                     }
  194.                     FreeVec(FN_SetFunc);    
  195.                 }
  196.             }
  197.             DeleteCxObj(broker);
  198.             DeletePort(nb.nb_Port);
  199.         }
  200.         FreeRemember(&grk, TRUE);
  201.     }
  202.     CloseLibs();
  203.     return(ret);
  204. }
  205.  
  206.  
  207. /***************************************************************************
  208.  * OpenCfg() -- Read in the preferences file.
  209.  */
  210. #define MULTILINE_TEMP "MULTILINE/A/K,COPYPASS=COPYPASSWD/S,AKA/F/A"
  211. #define OPT_NODE 0
  212. #define OPT_COPYPASS 1
  213. #define OPT_AKA 2
  214. #define OPT_MAX 3
  215. #define BUF_SIZE 1000
  216.  
  217. LONG OpenCfg(STRPTR filename)
  218. {
  219.     LONG nodesadded = 0;
  220.     if( mlines = AllocRemember(&grk, sizeof(struct MLList), MEMF_CLEAR) )
  221.     {
  222.         STRPTR buf;
  223.         NewList((struct List *)mlines);
  224.     
  225.         if( buf = AllocVec(BUF_SIZE, 0) )
  226.         {
  227.             BPTR file;
  228.             if( file = Open(filename, MODE_OLDFILE) )
  229.             {
  230.                 struct RDArgs *rda;
  231.                 if( rda = AllocDosObject(DOS_RDARGS, NULL) )
  232.                 {
  233.                     STRPTR nbuf;
  234.                     STRPTR args[OPT_MAX];
  235.                     rda->RDA_DAList = NULL;
  236.                     rda->RDA_Flags |= RDAF_NOPROMPT;
  237.                     for( nbuf = FGets(file, buf, BUF_SIZE-1); nbuf; nbuf = FGets(file, buf, BUF_SIZE-1) )
  238.                     {
  239.                         if( (nbuf[0] == 'm') || (nbuf[0] == 'M') )
  240.                         {
  241.                             rda->RDA_Buffer = NULL;
  242.                             rda->RDA_Source.CS_Buffer = nbuf;
  243.                             rda->RDA_Source.CS_Length = strlen(nbuf);
  244.                             rda->RDA_Source.CS_CurChr = 0;
  245.                             args[0] = NULL;
  246.                             args[1] = NULL;
  247.                             args[2] = NULL;
  248.                         
  249.                             if( ReadArgs(MULTILINE_TEMP, (LONG *)&args, rda)) 
  250.                             {
  251.                                 struct MLNode *mln;
  252.                                 /* Allocate a node */
  253.                                 if( mln = AllocRemember(&grk, sizeof(struct MLNode), MEMF_CLEAR) )
  254.                                 {
  255.                                     /* Parse the Addr */
  256.                                     if( GL_XtractInfos(&mln->ml_BaseNode, args[OPT_NODE]) )
  257.                                     {
  258.                                         /* Alloc memory for mln->ml_ReplaceWith */
  259.                                         if( mln->ml_ReplaceWith = AllocRemember(&grk, strlen(args[OPT_AKA])+1, 0) )
  260.                                         {
  261.                                             /* Copy replacements */
  262.                                             strcpy(mln->ml_ReplaceWith, args[OPT_AKA]);
  263.                                         
  264.                                             /* Should we copy the password? */
  265.                                             if( args[OPT_COPYPASS] )
  266.                                                 mln->ml_Flags |= MLFF_COPYPASS;
  267.                                         
  268.                                             /* This node has never been selected... */
  269.                                             mln->ml_Last = MLLAST_NONE;
  270.                                         
  271.                                             /* Add node to list */
  272.                                             AddTail((struct List *)mlines, (struct Node *)mln);
  273.                                             nodesadded++;
  274.                                         }
  275.                                     }
  276.                                 }
  277.                                 FreeArgs(rda);
  278.                             }
  279.                         }
  280.                     } 
  281.                     FreeDosObject(DOS_RDARGS, rda);
  282.                 }
  283.                 Close(file);
  284.             }
  285.             FreeVec(buf);
  286.         }
  287.     }
  288.     return nodesadded;
  289. }
  290.  
  291.  
  292. /***************************************************************************
  293.  * ShowWindow() -- Show our window... currently only a requester 
  294.  */
  295. BOOL ShowWindow(void)
  296. {
  297.     struct EasyStruct ez = {
  298.         sizeof(struct EasyStruct),
  299.         0,
  300.         "GMulti",
  301.         "%s ©Lee Kindness.\n\n"
  302.         "Internet: wangi@frost3.demon.co.uk\n"
  303.         "Fidonet: 2:259/15.46\n\n"
  304.         "Impoved multiline support for gotcha.library\n\n"
  305.         "Read \"GMulti.guide\" for more information\n\n"
  306.         "(Program may take a couple of seconds to quit)",
  307.         "Quit|Hide"
  308.     };
  309.     return((BOOL)EasyRequest(NULL, &ez, NULL, &vertag[6]));
  310. }
  311.  
  312.  
  313. /***************************************************************************
  314.  * OpenLibs() -- Open all used libraries
  315.  */
  316. BOOL OpenLibs(void)
  317. {
  318.     BOOL ret;
  319.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37);
  320.     CxBase = OpenLibrary("commodities.library", 37);
  321.     GotchaLibBase = OpenLibrary("gotcha.library", 0);
  322.     ret = ((IntuitionBase) && 
  323.            (CxBase) && 
  324.            (GotchaLibBase));
  325.     return(ret);
  326. }
  327.  
  328.  
  329. /***************************************************************************
  330.  * CloseLibs() -- Close all libraries
  331.  */
  332. void CloseLibs(void)
  333. {
  334.     if (GotchaLibBase)
  335.         CloseLibrary(GotchaLibBase);
  336.     if (CxBase)
  337.         CloseLibrary(CxBase);
  338.     if (IntuitionBase)
  339.         CloseLibrary((struct Library *)IntuitionBase);
  340. }
  341.  
  342.  
  343. /***************************************************************************
  344.  * BumpPhone() -- Select the next pnone number
  345.  */
  346. struct gl_nodeinfo *BumpPhone(struct gl_context *nl, struct gl_nodeinfo *nd,
  347.                     struct MLNode *mln, SetFunc *setfunc,
  348.                     struct gl_pattern *pat, struct Library *lib)
  349. {
  350.     #define BREAKCHARS "\t "
  351.     STRPTR s;
  352.     if( mln->ml_Last )
  353.         /* Skip to the next value in the string */
  354.         s = strpbrk(mln->ml_Last, BREAKCHARS);
  355.     else
  356.         /* Start at the begining */
  357.         s = mln->ml_ReplaceWith;
  358.     if( s )
  359.     {
  360.         STRPTR s2, s3;
  361.         BOOL pnum, fail;
  362.         LONG count;
  363.         fail = FALSE;
  364.         /* Skip white space */
  365.         s = stpblk(s);
  366.         
  367.         /* Find end of this item */
  368.         if( s2 = strpbrk(s, BREAKCHARS) )
  369.         {
  370.             /* Wow long is this item? and is it a phone number? */
  371.             pnum = TRUE;
  372.             count = 0;
  373.             s3 = s;
  374.             while( s3 != s2 )
  375.             {
  376.                 if( *s3 == ':' )
  377.                     /* its not a phone number */
  378.                     pnum = FALSE;
  379.                 count++;
  380.                 s3++;
  381.             }
  382.         } else
  383.         {
  384.             count = strlen(s);
  385.             if( strchr(s, ':') )
  386.                 pnum = FALSE;
  387.             else
  388.                 pnum = TRUE;
  389.         }
  390.         
  391.         /* If its a phone number then copy it */
  392.         if( pnum )
  393.         {
  394.             strncpy(nd->phone, s, 63);
  395.             strncpy(nd->tphone, s, 63);
  396.         } else
  397.         {
  398.             STRPTR fqfa;
  399.             /* it is a FQFA */
  400.             if( fqfa = AllocVec(count+1, 0) )
  401.             {
  402.                 struct gl_address *addr;
  403.                 strncpy(fqfa, s, count);
  404.                 if( addr = AllocVec(sizeof(struct gl_address), MEMF_CLEAR) )
  405.                 {
  406.                     if( GL_XtractInfos(addr, fqfa) )
  407.                     {
  408.                         FN_Caller Caller;
  409.                         struct gl_nodeinfo noded;
  410.                         struct gl_nodeinfo *nodedesc = &noded;
  411.                         
  412.                         /* Call original function to resolve the phone number */
  413.                         Caller = (APTR)setfunc->sf_OriginalFunc;
  414.                         if( Caller(addr, nl, nodedesc, pat, lib) )
  415.                         {
  416.                             USHORT tmp;
  417.                             
  418.                             swmem(nodedesc, nd, sizeof(struct gl_nodeinfo));
  419.  
  420.                             tmp = nodedesc->zone;
  421.                             nodedesc->zone = nd->zone;
  422.                             nd->zone = tmp;
  423.                             tmp = nodedesc->net;
  424.                             nodedesc->net = nd->net;
  425.                             nd->net = tmp;
  426.                             tmp = nodedesc->node;
  427.                             nodedesc->node = nd->node;
  428.                             nd->node = tmp;
  429.                             tmp = nodedesc->point;
  430.                             nodedesc->point = nd->point;
  431.                             nd->point = tmp;
  432.                             tmp = nodedesc->region;
  433.                             nodedesc->region = nd->region;
  434.                             nd->region = tmp;
  435.                             tmp = nodedesc->hub;
  436.                             nodedesc->hub = nd->hub;
  437.                             nd->hub = tmp;                            
  438.                             swmem(nodedesc->domain, nd->domain, 32);
  439.  
  440.                             if( (mln->ml_Flags & MLFF_COPYPASS) )
  441.                                 swmem(nodedesc->password, nd->password, 32);
  442.                         } else
  443.                             fail = TRUE;
  444.                     } else
  445.                         fail = TRUE;
  446.                     FreeVec(addr);
  447.                 } else
  448.                     fail = TRUE;
  449.                 FreeVec(fqfa);
  450.             } else
  451.                 fail = TRUE;
  452.         }
  453.         if( fail )
  454.             /* We are leaving ret->Phone as it is */
  455.             mln->ml_Last = MLLAST_BASENODE;
  456.         else
  457.             /* Update ml_Last */
  458.             mln->ml_Last = s;
  459.     } else
  460.         /* We are leaving ret->Phone as it is */
  461.         mln->ml_Last = MLLAST_BASENODE;
  462.     return nd;
  463. }
  464.  
  465.  
  466. /***************************************************************************
  467.  * FN_New() -- The GL_FindNode() replacement
  468.  */
  469.  
  470. LONG __saveds __asm FN_New( REG(a0) struct gl_address *find_me,
  471.                             REG(a1) struct gl_context *nl,
  472.                             REG(a2) struct gl_nodeinfo *ni,
  473.                             REG(a3) struct gl_pattern *pat,
  474.                             REG(a6) struct Library *lib)
  475. {
  476.     FN_Caller Caller;
  477.     LONG ret;
  478.     
  479.     /* increment count */
  480.     Forbid();
  481.     FN_SetFunc->sf_Count += 1;
  482.     Permit();
  483.     
  484.     Caller = (APTR)FN_SetFunc->sf_OriginalFunc;
  485.     
  486.     /* Pass the buck */
  487.     /* only do our stuff if we are an active cx */
  488.     if( (ret = Caller(find_me, nl, ni, pat, lib)) &&
  489.         (Active) )
  490.     {
  491.         struct MLNode *mln, *foundnode = NULL;
  492.         
  493.         /* Go thru our list of mlines, looking for a match */
  494.         mln = mlines->mllh_Head;
  495.         while( mln->ml_Succ ) 
  496.         {
  497.             if( !GL_AdrCmpPat(&mln->ml_BaseNode, find_me) )
  498.             {
  499.                 foundnode = mln;
  500.             }
  501.             mln = mln->ml_Succ;
  502.         }
  503.         if (foundnode) 
  504.         {
  505.             if( foundnode->ml_Last == MLLAST_NONE )
  506.             {
  507.                 /* Use ni->Phone as it is, and update ml_Last */
  508.                 foundnode->ml_Last = MLLAST_BASENODE;
  509.             }
  510.             else
  511.             {
  512.                 /* Get the next phone number */
  513.                 BumpPhone(nl, ni, foundnode, FN_SetFunc, pat, lib);
  514.             }
  515.         }
  516.     }
  517.     
  518.     /* decrement count */
  519.     Forbid();
  520.     FN_SetFunc->sf_Count -= 1;
  521.     Permit();
  522.     
  523.     /* and return */
  524.     return(ret);
  525. }
  526.